﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using SQLServerHealthCheck.SQLServer;
using System.Collections.ObjectModel;
using SQLServerHealthCheck.Model;
using System.Windows.Threading;
using SQLServerHealthCheck.SQLServer.IssueTypes;
using SQLServerOptimizer.PL.WPF;
using SQLServerOptimizer.PL.WPF.Properties;

namespace SQLServerOptimizer.PL.WPF
{

    public delegate List<Exception> RunCollectData(SQLServerInstance sqlServerInstance);

    public delegate void ProgressUpdateEvent(SQLServerInstance Instance, String Task, Decimal Status);

    public delegate void ProccesCompleted();

    public delegate void IssueCheckStart(SQLServerInstance Instance);

    public class DataCollectionWorker : AsyncUtils.AsyncOperation
    {

        public event ProgressUpdateEvent ProgressUpdate;
        public event ProccesCompleted ProccessCompleted;
        public event IssueCheckStart IssueCheckStart;
        public int countEventsCalls = 0;
        private ObservableCollection<SQLServerInstance> sqlServerInstances;
        public static List<Exception> errors;        
        public Decimal Status;
   
        public DataCollectionWorker(DispatcherObject target, ObservableCollection<SQLServerInstance> SQLServerInstances)
            : base(target)
        {
            sqlServerInstances = SQLServerInstances;

        }
       

        
        public void Fail()
        {
            lock (this)
            {
                _fail = true;
            }
        }
        private bool _fail;
        protected override void DoWork()
        {
            lock (this)
            {
                (new CollectServerAndServiceData()).ClearAll();

                _fail = false;

                foreach (SQLServerInstance sqlServerInstance in sqlServerInstances)
                {

                    if (!CancelRequested)
                    {
                        RunCollectData runCollectdata = new RunCollectData(CollectInstanceDataAsync);
                        runCollectdata.BeginInvoke(sqlServerInstance, null, null);
                    }
                    if (_fail)
                    {
                        throw new Exception();
                    }

                }
                if (CancelRequested)
                {
                    AcknowledgeCancel();
                }
            }
        }
        private List<Exception> CollectInstanceDataAsync(SQLServerInstance instance)
        {

            List<Exception> errors = new List<Exception>();

            bool SettingsCollectColumndetails = false;
            
          SettingsCollectColumndetails = SQLServerOptimizer.PL.WPF.Properties.Settings.Default.CollectColumndetails;
          (new CollectServerAndServiceData()).ClearAll();
          if (!CancelRequested)
          {

              FireProgressUpdateEvent(instance, "Collect Server And Service Data", 2);
              errors.AddRange((new CollectServerAndServiceData()).Collect(instance));
          }




            if (!CancelRequested)
            {

                FireProgressUpdateEvent(instance, "Collecting Databases Data", 30);
                errors.AddRange((new CollectDatabasesData()).Collect(instance));
            }



            bool CollectPerformanceData = SQLServerOptimizer.PL.WPF.Properties.Settings.Default.CollectIndexStatistics; 

            if (CollectPerformanceData)
            {
                if (!CancelRequested)
                {
                    FireProgressUpdateEvent(instance, "Collecting Performance Data", 70);
                    errors.AddRange((new CollectPerformanceData()).Collect(instance, SettingsCollectColumndetails));
                }

            }

            if (!CancelRequested)
            {
                FireProgressUpdateEvent(instance, "Collecting Security Data", 80);
                errors.AddRange((new CollectSecurityData()).Collect(instance));
            }


            if (!CancelRequested)
            {
                FireProgressUpdateEvent(instance, "Collecting SQL Agent Data", 85);
                errors.AddRange((new CollectSQLAgentData()).Collect(instance));
            }

            
            if (!CancelRequested)
            {
                FireProgressUpdateEvent(instance, "Data collection Completed", 100);
            }
            countEventsCalls++;
            FireProccessCompletedEvent();
            return errors;

        }
        private void FireProgressUpdateEvent(SQLServerInstance Instance, String Task, Decimal status)
        {
            Object[] param = new Object[] { Instance, Task, status };
            
            FireAsync(ProgressUpdate, param);
        }
       
        private void FireProccessCompletedEvent()
        {
            if (countEventsCalls == (sqlServerInstances.Count))
            {
                (new CheckSQLServerInstancesForIssues()).RunIssueChecks();
                FireAsync(ProccessCompleted);
                countEventsCalls = 0;
            }

        }

        // Property changed event handler         
            }   
}
